
#pragma once

#include "ttg/services.h"
#include "ttg/pipeline.h"
#include "PerfTestUtils.h"

using namespace System;
using namespace ttg;
using namespace ttg::pipeline;

class DisbNode: public TimeWasterNode<int> {
protected:
	virtual void postWaste(double data, const int &) {
		for (int i = 0; i < this->getParametrizedOutputs().size(); i++)
			getParametrizedOutputs()[i]->sendThis(make_pair(data * (i + 1), 0));
	}
};

namespace ttg_internal
{
	namespace utils
	{

		///<summary>
		///
		///
		///</summary>
		public ref class DisbalancedTreeTest
		{
			typedef pair<double, int> myType;
			private:
				///<summary>
				///Generating conveyor in form of full ternary tree with height == depth
				///
				///</summary>
				static ttg::pipeline::NodeWrapper<myType, myType> createDisbNodes(size_t depth)
				{
					//Creating wrapper for first item x/1!
					if (depth <= 1) return wrap(new DisbNode());
					return wrap(new DisbNode()) + (createDisbNodes(depth - 1) * createDisbNodes(depth - 1) * createDisbNodes(depth - 1));

				}
			public:
				//performs
				static double perform(size_t layer_count, size_t thread_count)
				{
					if (layer_count > 0 && thread_count > 0)
					{
						//Preparing pipeline
						Pipeline<myType, myType> *pl
							//Avast!
							= new Pipeline<myType, myType>(/*thread_count,*/ createDisbNodes(layer_count));
						//Launching
						double t_start = ttg::services::ServiceBase::_Timer().getMilliSeconds();
						pl->start(make_pair(1.0, 0));
						double t_end = ttg::services::ServiceBase::_Timer().getMilliSeconds();
						//Returning elapsed time
						SAFE_DELETE(pl);
						return t_end - t_start;
					}
					else
						return 0.0;
				}
		};
	}
}
